package com.imot.handler;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imot.pojo.entity.*;
import com.imot.service.*;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName: JsonServerHandler
 * Description:
 * date: 2023/11/12 20:22
 *
 * @author imot-jiah.wang
 */
@Slf4j
@ChannelHandler.Sharable
@Component
public class JsonServerHandler extends SimpleChannelInboundHandler<String> {

    private final ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private IEmaRecordService recordService;
    @Autowired
    private ITargetParametersService targetParametersService;
    @Autowired
    private IEmaExceptionRecordService exceptionRecordService;
    @Autowired
    private IExceptionThresholdsService thresholdsService;
    @Autowired
    private IEmaRecordShortTermService recordShortTermService;
    @Autowired
    private IEmaRecordMidTermService recordMidTermService;
    @Autowired
    private IEmaRecordExtendedTermService emaRecordExtendedTermService;
    @Autowired
    private IEmaRecordLongTermService emaRecordLongTermService;
    @Autowired
    private IEmaErrorRecordService emaErrorRecordService;
    @Autowired
    private IErrorRecordService errorRecordService;

    @Override
    @Transactional
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

        List<EmaRecord> records = new ArrayList<>();
        ArrayList<EmaErrorRecord> emaErrorRecords = new ArrayList<>();
        ArrayList<ErrorRecord> errorRecords = new ArrayList<>();
        JsonNode arrayNode;

        boolean isFirstIteration = true;
        try {
            arrayNode = objectMapper.readTree(msg);
            log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~{}",arrayNode);
            log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~{}",arrayNode.toString());

            Integer id = null;
            for (JsonNode node : arrayNode) {
                log.info("!!!!!!!!!!!!!!!!!!!{}",node);
                try {
                    EmaRecord record = objectMapper.treeToValue(node, EmaRecord.class);
                    log.info("~~~~~~~~~~~~~~~{}",record);
                    if (isFirstIteration) {
                        String isError = record.getIsError();
                        if (isError != null) {
                            recordService.save(record);
                            id = record.getId();
                            EmaErrorRecord emaErrorRecord = new EmaErrorRecord();
                            BeanUtils.copyProperties(record, emaErrorRecord);
                            emaErrorRecord.setEmaRecordId(id);
                            emaErrorRecordService.save(emaErrorRecord);

                            ErrorRecord errorRecord = new ErrorRecord();
                            BeanUtils.copyProperties(record, errorRecord);
                            emaErrorRecord.setEmaRecordId(id);
                            errorRecordService.save(errorRecord);
                            isFirstIteration = false;
                            continue;
                        }
                    }
                    if (isFirstIteration) {
                        records.add(record);
                    } else {
                        ErrorRecord errorRecord = new ErrorRecord();
                        BeanUtils.copyProperties(record, errorRecord);
                        errorRecord.setId(id);
                        errorRecords.add(errorRecord);
                    }

                } catch (JsonProcessingException e) {
                    // 这条记录有问题，跳过它
//                    log.info(e.getMessage());
//                    log.info("这条信息接受错误：请及时查看：" + node);
                    continue;
                }
            }

            if (!isFirstIteration) {
                errorRecordService.saveBatch(errorRecords);
            }
        } catch (JsonProcessingException e) {
            // 处理读取整个消息的错误
            log.info("读取信息错误");
        }
        recordService.saveBatch(records);
        LambdaQueryWrapper<TargetParameters> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.last("limit 1");
        queryWrapper.orderByDesc(TargetParameters::getId);
        TargetParameters targetParameters = targetParametersService.getOne(queryWrapper);

        saveExceptionRecord(records, targetParameters);
        recordService.updateBatchById(records);

        saveErrordiff(records);


    }

    public void saveErrordiff(List<EmaRecord> records) {
        List<Integer> list = records.stream().map(EmaRecord::getId).collect(Collectors.toList());
        log.info("lalallala{}",list);
        if (records != null && records.size() == 1) {
            EmaRecord emaRecord = records.get(0);
            EmaRecordShortTerm emaRecordShortTerm = new EmaRecordShortTerm();
            EmaRecordMidTerm emaRecordMidTerm = new EmaRecordMidTerm();
            EmaRecordExtendedTerm emaRecordExtendedTerm = new EmaRecordExtendedTerm();
            EmaRecordLongTerm emaRecordLongTerm = new EmaRecordLongTerm();
            Integer id = emaRecord.getId();
            //一小时
            if (id % 12 == 0) {
                BeanUtils.copyProperties(emaRecord, emaRecordShortTerm);
                recordShortTermService.save(emaRecordShortTerm);
            }
            //十二个小时
            if (id % (12 * 12) == 0) {
                BeanUtils.copyProperties(emaRecord, emaRecordMidTerm);
                recordMidTermService.save(emaRecordMidTerm);
            }
            //六天
            if (id % (12 * 12 * 12) == 0) {
                BeanUtils.copyProperties(emaRecord, emaRecordExtendedTerm);
                emaRecordExtendedTermService.save(emaRecordExtendedTerm);
            }
            //七十二天
            if (id % (12 * 12 * 12 * 12) == 0) {
                BeanUtils.copyProperties(emaRecord, emaRecordLongTerm);
                emaRecordLongTermService.save(emaRecordLongTerm);
            }
        }
    }

    //增加故障记录
    public void saveErrorRecord(List<EmaRecord> records, TargetParameters targetParameters) {
        for (EmaRecord record : records) {
            ArrayList<String> list = new ArrayList<>();
            ArrayList<ExceptionThresholds> exceptionThresholds = new ArrayList<>();
            boolean location = evaluateThreshold(record, targetParameters, list, exceptionThresholds);
            String exceptionParameters = list.stream().collect(Collectors.joining());
            if (list != null && list.size() > 0) record.setIsException("1");
            EmaExceptionRecord emaExceptionRecord = new EmaExceptionRecord();

            emaExceptionRecord.setEmaRecordId(record.getId());
            emaExceptionRecord.setExceptionParameters(exceptionParameters);
            emaExceptionRecord.setTargetParametersId(targetParameters.getId());
            emaExceptionRecord.setDate(record.getTime());
            if (location) {
                exceptionRecordService.save(emaExceptionRecord);
                Integer id = emaExceptionRecord.getId();
                List<ExceptionThresholds> thresholdsList = exceptionThresholds.stream().distinct().collect(Collectors.toList());
                thresholdsList.stream().forEach(exceptionThreshold -> exceptionThreshold.setEmaExceptionRecordId(id));
                thresholdsService.saveBatch(thresholdsList);
            }
        }
    }

    //增加异常记录
    public void saveExceptionRecord(List<EmaRecord> records, TargetParameters targetParameters) {
        for (EmaRecord record : records) {
            ArrayList<String> list = new ArrayList<>();
            ArrayList<ExceptionThresholds> exceptionThresholds = new ArrayList<>();
            boolean location = evaluateThreshold(record, targetParameters, list, exceptionThresholds);
            String exceptionParameters = list.stream().collect(Collectors.joining());
            if (list != null && list.size() > 0) record.setIsException("1");
            EmaExceptionRecord emaExceptionRecord = new EmaExceptionRecord();

            emaExceptionRecord.setEmaRecordId(record.getId());
            emaExceptionRecord.setExceptionParameters(exceptionParameters);
            emaExceptionRecord.setTargetParametersId(targetParameters.getId());
            emaExceptionRecord.setDate(record.getTime());
            if (location) {
                exceptionRecordService.save(emaExceptionRecord);
                Integer id = emaExceptionRecord.getId();
                List<ExceptionThresholds> thresholdsList = exceptionThresholds.stream().distinct().collect(Collectors.toList());
                thresholdsList.stream().forEach(exceptionThreshold -> exceptionThreshold.setEmaExceptionRecordId(id));
                thresholdsService.saveBatch(thresholdsList);
            }
        }
    }

    //异常记录的筛选
    public boolean evaluateThreshold(EmaRecord emaRecord, TargetParameters targetParameters, ArrayList<String> list, ArrayList<ExceptionThresholds> exceptionThresholds) {
        boolean location = false;
        if (targetParameters != null) {
            Float motorSpeed = emaRecord.getMotorSpeed();
            Float motorCurrent = emaRecord.getMotorCurrent();
            Float temperature = emaRecord.getTemperature();
            Float supplyVoltage = emaRecord.getSupplyVoltage();

            Float targetRpm = targetParameters.getTargetRpm();
            Float targetCurrent = targetParameters.getTargetCurrent();
            Float minTempThresh = targetParameters.getMinTempThresh();
            Float maxTempThresh = targetParameters.getMaxTempThresh();
            Float minVoltThresh = targetParameters.getMinVoltThresh();
            Float maxVoltThresh = targetParameters.getMaxVoltThresh();

            Float rpmDiff = targetRpm - motorSpeed;
            Float currentDiff = targetCurrent - motorCurrent;
            Float temMindiff = temperature - minTempThresh;
            Float temMaxdiff = maxTempThresh - temperature;
            Float volMindiff = supplyVoltage - minVoltThresh;
            Float volMaxdiff = maxVoltThresh - supplyVoltage;

            if (currentDiff < 0) {
                ExceptionThresholds exceptionThreshold = new ExceptionThresholds();
                exceptionThreshold.setExceptionParameter("电流");
                exceptionThreshold.setUpperThreshold(targetCurrent);
                exceptionThresholds.add(exceptionThreshold);
                list.add("电流：" + motorCurrent + "。");
                location = true;
            }
            if (rpmDiff < 0) {
                ExceptionThresholds exceptionThreshold = new ExceptionThresholds();
                exceptionThreshold.setExceptionParameter("转速");
                exceptionThreshold.setUpperThreshold(targetRpm);
                exceptionThresholds.add(exceptionThreshold);
                list.add("转速：" + motorSpeed + "。");
                location = true;
            }
            if (temMindiff < 0) {
                ExceptionThresholds exceptionThreshold = new ExceptionThresholds();
                exceptionThreshold.setExceptionParameter("温度");
                exceptionThreshold.setLowerThreshold(minTempThresh);
                exceptionThreshold.setUpperThreshold(maxTempThresh);
                exceptionThresholds.add(exceptionThreshold);
                list.add("温度：" + temperature + "。");
                location = true;
            }
            if (temMaxdiff < 0) {
                ExceptionThresholds exceptionThreshold = new ExceptionThresholds();
                exceptionThreshold.setExceptionParameter("温度");
                exceptionThreshold.setLowerThreshold(minTempThresh);
                exceptionThreshold.setUpperThreshold(maxTempThresh);
                exceptionThresholds.add(exceptionThreshold);
                list.add("温度：" + temperature + "。");
                location = true;
            }
            if (volMindiff < 0) {
                ExceptionThresholds exceptionThreshold = new ExceptionThresholds();
                exceptionThreshold.setExceptionParameter("电压");
                exceptionThreshold.setUpperThreshold(minVoltThresh);
                exceptionThreshold.setUpperThreshold(maxVoltThresh);
                exceptionThresholds.add(exceptionThreshold);
                list.add("电压：" + supplyVoltage + "。");
                location = true;
            }
            if (volMaxdiff < 0) {
                ExceptionThresholds exceptionThreshold = new ExceptionThresholds();
                exceptionThreshold.setExceptionParameter("电压");
                exceptionThreshold.setUpperThreshold(minVoltThresh);
                exceptionThreshold.setUpperThreshold(maxVoltThresh);
                exceptionThresholds.add(exceptionThreshold);
                list.add("电压：" + supplyVoltage + "。");
                location = true;
            }
        }
        return location;
    }
}



